package ppd;



/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 *
 * @author bastien
 */
public class TableImpl extends UnicastRemoteObject implements Table {

    Buveur assis;
    ArrayList<Table> voisines;
    CyclicBarrier cb;
    

    /**
     * Cree une table qui cree un buveur et l'assoit
     * @param localIp
     * @param taille_verre
     * @throws RemoteException
     */
    public TableImpl(int taille_verre) throws RemoteException{
        System.out.println("Un buveur s'assoit avec un verre de "+taille_verre+" gorgees.");
        assis = new BuveurImpl(taille_verre);
        voisines=new ArrayList<Table>();

    }
    
    public TableImpl(int taille_verre, int nb_tables) throws RemoteException{
        System.out.println("Un buveur s'assoit avec un verre de "+taille_verre+" gorgees.");
        assis = new BuveurImpl(taille_verre);
        voisines=new ArrayList<Table>();
        cb=new CyclicBarrier(nb_tables);

    }
            

    public int nombreTableVoisines() throws RemoteException {
        return voisines.size();
    }

    public Buveur buveurAssis() throws RemoteException {
        return assis;
    }

    public ArrayList<Table> tablesVoisines() {
        return voisines;
    }

    public synchronized void addVoisin(String Ip){
        boolean recupere=false;
        int nbsec=0;
        Table od=null;

        while(!recupere && nbsec<15){
            try{
            	System.out.println("Tentative de connexion a l'hote "+Ip+" numero "+(nbsec+1));
                od=(Table)Naming.lookup("//"+Ip+":10070/table");
                recupere=true;
            }
            catch(NotBoundException n){ if(nbsec>=15) {System.out.println("Apres 15 tentatives de connexion, l'hote ne repond pas, abandon de la procedure de connexion..."); System.exit(0);}try{ wait(2000); recupere=false;} catch(InterruptedException i){} nbsec++;}
            catch(MalformedURLException m){System.err.println("L'url suivante : \""+Ip+":10070/table\" est mal formee."); return;}
            catch(RemoteException r){System.err.println("Une exception de type RemoteException est survenue lors de la tentative de connexion a l'hote "+Ip+". L'Annuaire Rmi n'est sans doute pas encore lance sur la machine distante."); try{wait(2000); recupere=false;}catch(Exception e){} nbsec++;}
        }
        voisines.add(od);

    }

    public synchronized void servir(Barman t){
	try{ this.wait(2000);}catch(Exception e) { System.out.println("Le barman a rendu son tablier a cause du stress... "+e.getClass());}
        new Thread((BarmanImpl)t).start();
        
    }
    
    public void attendre() throws InterruptedException, BrokenBarrierException{
        cb.await();
    }
    
    public void attendre(String ipCentrale){
        try{
            Table t=(Table)Naming.lookup("//"+ipCentrale+":10070/table");
            t.attendre();
        }
        catch(NotBoundException n){ System.err.println("La table centrale n'a pas d'objet dans son RmiRegistry, elle en avait un il y a quelques secondes, elle doit donc etre morte..."); System.exit(0);}
        catch(MalformedURLException m){System.err.println("L'url suivante : \""+ipCentrale+":10070/table\" est mal formee."); System.exit(0);}
        catch(Exception e){ System.err.println("Une exception de type "+e.getClass()+" est survenue dans la methode TableImpl.attendre()."); System.exit(0);}
    	System.out.println("Toutes les tables sont posées et les clients assis. Demarrage de la simulation...");
    }
    
    public void start(){
    	new Thread((BuveurImpl)assis).start();
	}



}
